/***************************************************************************
 *    
 *      Copyright (c) 2009,2010 KaiTrade LLC (Delaware)
 *                     All Rights Reserved Worldwide
 *
 * STRICTLY PROPRIETARY and CONFIDENTIAL
 *
 * WARNING:  This file is the confidential property of KaiTrade LLC For
 * use only by those with the express written permission and license from
 * KaiTrade LLC.  Unauthorized reproduction, distribution, use or disclosure 
 * of this file or any program (or document) is prohibited. 
 * 
 ***************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;

namespace PlugIn
{
    /// <summary>
    /// The plugin class impliments the client interface to get notifications about executions and the
    /// subscriber interface to get price updates
    /// </summary>
    public partial class PlugInControl : UserControl, KaiTrade.Interfaces.Client, KaiTrade.Interfaces.Subscriber
    {
        /// <summary>
        /// Group used to historic data
        /// </summary>
        private KaiTrade.Interfaces.TSQueryGroup m_TSQueryGroup;

        //Need to swap update threads - for price updates
        public delegate void ProcessImage(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList);
        public ProcessImage m_ProcessImage;
        public delegate void ProcessUpdate(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList);
        public ProcessUpdate m_ProcessUpdate;
        public delegate void ProcessMessage(KaiTrade.Interfaces.Message myMessage);
        public ProcessMessage m_ProcessMessage;

        public PlugInControl()
        {
            InitializeComponent();
            // these are used to invoke updates on the correct thread
            m_ProcessImage = new ProcessImage(this.applyImage);
            m_ProcessUpdate = new ProcessUpdate(this.applyUpdate);
            m_ProcessMessage = new ProcessMessage(this.applyMessage);
            
        }

        /// <summary>
        /// Called from the Plugin main class - when the main app wants us to start
        /// </summary>
        public void Start()
        {
            try
            {

                KaiTrade.Interfaces.Facade myFacade = Factory.Instance().AppFacade;

                // This will register this object for updates from the facade
                Factory.Instance().AppFacade.Register("PI:" + "123", this);

            }
            catch (Exception myE)
            {

            }
        }

        /// <summary>
        /// Called from the PlugIn class - when the main app wants us to stop
        /// </summary>
        public void Stop()
        {
        }

        /// <summary>
        /// Example of how to send a KAI message for order routing
        /// </summary>
        /// <param name="myMsg"></param>
        public void Send(KaiTrade.Interfaces.Message myMsg)
        {
            try
            {
                KaiTrade.Interfaces.Facade myFac = Factory.Instance().AppFacade;
                if (myFac != null)
                {
                    // send this message to the facade for order routing
                    myFac.SendOR(myMsg);
                }

            }
            catch (Exception myE)
            {
                //m_Log.Error("Send", myE);
            }
        }

        /// <summary>
        /// Subscribe to real time prices for the menmonic
        /// </summary>
        /// <param name="productMnemonic"></param>
        private void subscribePrices(string productMnemonic)
        {
            try
            {
                KaiTrade.Interfaces.Facade myFacade = Factory.Instance().AppFacade;
                KaiTrade.Interfaces.Publisher myPub = null;

                // This will return a publisher for the mnemonic specified
                myPub = myFacade.GetPXPublisher(productMnemonic);

                if (myPub != null)
                {
                    // here you can associate a subscriber with the publisher
                    // you will be evented 
                    myPub.Subscribe(this);

                }

            }
            catch (Exception myE)
            {
                //m_Log.Error(SubscribePrices", myE);
            }
        }

        /// <summary>
        /// Shows how to unsubscribe to prices for a given mnemomic
        /// </summary>
        /// <param name="myMnemonic"></param>
        private void unSubscribePrices(string myMnemonic)
        {
            try
            {
                KaiTrade.Interfaces.Facade myFacade = Factory.Instance().AppFacade;
                KaiTrade.Interfaces.Publisher myPub = null;

                myPub = myFacade.GetPXPublisher(myMnemonic);

                if (myPub != null)
                {
                    myPub.UnSubscribe(this);
                }

            }
            catch (Exception myE)
            {
                //m_Log.Error("unSubPrices", myE);
            }
        }

        /// <summary>
        /// This shows you how to open a query group file
        /// to get historic data from CQG
        /// </summary>
        /// <param name="myPath"></param>
        /// <param name="myMnemonic"></param>
        private void loadGroup(string myPath, string myMnemonic)
        {
            try
            {
                KAI.kaitns.TSQueryGroup myGrpDB = new KAI.kaitns.TSQueryGroup();
                myGrpDB.FromXmlFile(myPath);

                m_TSQueryGroup = Factory.Instance().AppFacade.Factory.GetTSSetManager().CreateTSQueryGroup();
                m_TSQueryGroup.FromXmlDB(myGrpDB);

                m_TSQueryGroup.Mnemonic = myMnemonic;

                // Here we suscribe to updates from the group - e.g. when a bar is added
                m_TSQueryGroup.addSubscriber(this);

            }
            catch (Exception myE)
            {
                //m_Log.Error("loadGroup", myE);
            }
        }
    

        #region Subscriber Members

        public void OnImage(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList)
        {
            try
            {

                this.Parent.Invoke(this.m_ProcessImage, new object[] { mySender, itemList });

            }
            catch (Exception myE)
            {
                //m_Log.Error("OnImage", myE);
            }
        }

        public void OnStatusChange(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList)
        {
            try
            {

                

            }
            catch (Exception myE)
            {
                //m_Log.Error("OnStatusChange", myE);
            }
        }

        public void OnUpdate(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList)
        {
            try
            {

                this.Parent.Invoke(this.m_ProcessUpdate, new object[] { mySender, itemList });


            }
            catch (Exception myE)
            {
                //m_Log.Error("OnUpdate", myE);
            }

        }

        private void applyImage(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList)
        {
            try
            {
                KaiTrade.TradeObjects.PXPublisher myPXPub = mySender as KaiTrade.TradeObjects.PXPublisher;
                if (myPXPub != null)
                {

                    txtBidPx.Text = myPXPub.BidPrice;
                    txtBidSz.Text = myPXPub.BidSize;
                    txtOfferPx.Text = myPXPub.OfferPrice;
                    txtOfferSz.Text = myPXPub.OfferSize;
                    txtTradePx.Text = myPXPub.TradePrice;
                }
            }
            catch (Exception myE)
            {
                
            }
        }
        private void applyUpdate(KaiTrade.Interfaces.Publisher mySender, List<KaiTrade.Interfaces.Field> itemList)
        {
            try
            {

                KaiTrade.TradeObjects.PXPublisher myPXPub = mySender as KaiTrade.TradeObjects.PXPublisher;
                if (myPXPub != null)
                {

                    txtBidPx.Text = myPXPub.BidPrice;
                    txtBidSz.Text = myPXPub.BidSize;
                    txtOfferPx.Text = myPXPub.OfferPrice;
                    txtOfferSz.Text = myPXPub.OfferSize;
                    txtTradePx.Text = myPXPub.TradePrice;
                }
            }
            catch (Exception myE)
            {
                
            }

        }

        #endregion

        #region Client Members
        private void applyMessage(KaiTrade.Interfaces.Message myMessage)
        {
            try
            {
                // typically you will handle execution reports in here
                if (myMessage.Label == "8")
                {
                    // Exec report processing
                    lstResults.Items.Add(myMessage.Data);
                }
               
            }
            catch (Exception myE)
            {

            }

        }

        void KaiTrade.Interfaces.Client.OnMessage(KaiTrade.Interfaces.Message myMessage)
        {
            this.Parent.Invoke(this.m_ProcessMessage, new object[] { myMessage });
        }

        void KaiTrade.Interfaces.Client.OnStatusMessage(KaiTrade.Interfaces.Message myMessage)
        {
            this.Parent.Invoke(this.m_ProcessMessage, new object[] { myMessage });
        }

        #endregion

        private void btnGetPrices_Click(object sender, EventArgs e)
        {
            try
            {
                subscribePrices(txtMnemonic.Text);
            }
            catch (Exception myE)
            {
            }
        }

        private void btnSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                int qty = int.Parse(txtQty.Text);
                Factory.Instance().AppFacade.SubmitStrategyOrder("PlugIn", txtMnemonic.Text, qty, 99, KaiTrade.Interfaces.Side.BUY, KaiTrade.Interfaces.OrderType.LIMIT);
                
            }
            catch (Exception myE)
            {
            }
        }
    }
}
